package com.ruoyi.controller;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.domain.vo.*;
import com.ruoyi.service.IUserCenterService;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.IAddressService;
import com.ruoyi.system.service.IOrderItemService;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.IUserInfoService;
import com.ruoyi.system.service.impl.UserInfoServiceImpl;
import com.ruoyi.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.UUID;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Controller
@ResponseBody
@RequestMapping("/wechatApp/userCenter")
public class UserCenterController extends BaseController {

    @Autowired
    private IUserCenterService userCenterService;
    @Autowired
    private ISysDictDataService dictDataService;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private IAddressService addressService;
    @Autowired
    private IOrderItemService orderItemService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private JwtUtil jwtUtil;


    /**
     *  登录
     *  @param account 用户账号
     *  @param password 用户密码
     *  @return 用户登录状态
     */
    @PostMapping("/login")
    @ResponseBody
    public AjaxResult login(@RequestParam("account") String account, @RequestParam("password") String password) {
        UserInfo user = userInfoService.selectUserInfoByAccount(account);
        if(user  == null){
            return error("用户不存在");
        }
        else if(Objects.equals(user.getPassword(), password)){
            return AjaxResult.success(user.getUserId());
        }
        return error("账号或密码错误");
    }

//    /**
//     *  登录
//     *  @param wechat 用户微信号
//     *  @return 用户登录状态
//     */
//    @PostMapping("/loginByWechat")
//    @ResponseBody
//    public AjaxResult loginByWechat(@RequestParam("wechat") String wechat) {
//        UserInfoVo user = userCenterService.selectUserInfoByWechat(wechat);
//        if(user  == null){
//            return error("用户不存在");
//        }
//        return success("登录成功");
//    }

    @PostMapping("/loginByWechat")
    public AjaxResult loginByWechat(@RequestParam("code") String code) {
        logger.info("Received login request with code: {}", code);
        System.out.println(1111);
        System.out.println(code);

        // 调用微信接口获取 session key 和 openid
        String appId = "wx9e584abdcd96775e"; // 建议使用配置文件或环境变量管理
        String secret = "7e76c375af7d576f478738188e2b2cba"; // 建议使用配置文件或环境变量管理
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
        String result = restTemplate.getForObject(url, String.class);
        System.out.println("WeChat API response: {}");
        logger.info("WeChat API response: {}", result);

        try {
            ObjectMapper mapper = new ObjectMapper();
            Map<String, String> sessionData = mapper.readValue(result, Map.class);

            if (sessionData.containsKey("errcode")) {
                logger.error("Failed to get user info: {}", sessionData.get("errmsg"));
                return AjaxResult.error("获取用户信息失败：" + sessionData.get("errmsg"));
            }

            String openid = sessionData.get("openid");
            System.out.println(222);
            System.out.println(openid);
            String sessionKey = sessionData.get("session_key");
            System.out.println(sessionKey);

            if (openid == null || openid.isEmpty()) {
                logger.error("Openid is null or empty");
                return AjaxResult.error("获取用户信息失败");
            }

            System.out.println(333);
            // 根据 openid 获取或创建用户信息
            UserInfoVo user = userCenterService.selectUserInfoByOpenid(openid);
            System.out.println(444);
            System.out.println("user:");
            System.out.println(user);
            System.out.println("User info by openid {}: {}");
            logger.info("User info by openid {}: {}", openid, user);

            if (user == null) {
                // 如果用户不存在，则创建新用户
                UserInfoVo userInfo = new UserInfoVo();
                userInfo.setOpenid(openid);
                userInfo.setSessionKey(sessionKey);
                // 设置其他用户信息，如昵称、头像等
                // 示例：userInfo.setNickname("默认昵称");
                userInfo.setNickName("微信用户");
                UUID uuid = UUID.randomUUID();
                String uuidStr = uuid.toString().replaceAll("-", "");
                String account = uuidStr.substring(0, 10);
                while (userCenterService.selectUserInfoByAccount(account) != null){
                    uuid = UUID.randomUUID();
                    uuidStr = uuid.toString().replaceAll("-", "");
                    account = uuidStr.substring(0, 10);
                }
                userInfo.setAccount(account);
                userCenterService.insertUserInfo(userInfo);
                logger.info("New user created with openid: {}", openid);
                user = userInfo; // 获取新创建的用户信息
            }

            // 生成 token 或其他登录凭证
            String token = jwtUtil.generateToken(user.getOpenid());

            System.out.println(555);
            System.out.println(token);
            // 返回 token 和 userId
            Map<String, Object> data = new HashMap<>();
            data.put("token", token);
            data.put("userId", user.getUserId());
            data.put("account", user.getAccount());
            return AjaxResult.success(data);
        } catch (Exception e) {
            logger.error("Login failed: {}", e.getMessage(), e);
            return AjaxResult.error("登录失败：" + e.getMessage());
        }
    }


    /**
     *  获取用户信息
     *  @param account 用户账号
     *  @return 用户详细信息
     */
    @GetMapping("/userInfo")
    public AjaxResult getInfo(@RequestParam("account") String account)
    {
        return AjaxResult.success(userCenterService.selectUserInfoByAccount(account));
    }

    /**
     * 修改用户信息
     */
    @RequestMapping("/edit")
    @PutMapping
    public AjaxResult edit(@RequestBody UserInfoVo userInfoVo)
    {
        UserInfo userInfo = new UserInfo();
        Long titleCode =dictDataService.selectDictValueByLabel(userInfoVo.getTitle());
        userInfo.setTitleCode(titleCode);
        userInfo.setUserId(userInfoVo.getUserId());
        userInfo.setAvatarAddress(userInfoVo.getAvatarAddress());
        userInfo.setNickName(userInfoVo.getNickName());
        userInfo.setPhone(userInfoVo.getPhone());
        userInfo.setCo2Reduce(userInfoVo.getCo2Reduce());
        userInfo.setOrganization(userInfoVo.getOrganization());
        userInfo.setPersonResume(userInfoVo.getPersonResume());
        userInfo.setRealName(userInfoVo.getRealName());
        userInfo.setUserId(userInfoVo.getUserId());
        return toAjax(userCenterService.updateUserInfo(userInfo));
    }

    /**
     *  获取用户低碳行为记录获取用户信息
     *  @param userId 用户ID
     *  @return 低碳行为记录
     */
    @GetMapping("/behavior")
    public AjaxResult getBehavior(@RequestParam("userId") Long userId, @RequestParam(value="pageNum", required = false, defaultValue = "1") Long pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Long pageSize)
    {
        List<BehaviorRecode> list = userCenterService.selectBehaviorByUserID(userId, pageNum, pageSize);
        return AjaxResult.success(list);
    }

    /**
     * 获取用户低碳活动记录
     *  @param userId 用户ID
     *  @return 低碳活动记录
     */
    @GetMapping("/activityLog")
    public AjaxResult getActivityLog(@RequestParam("userId") Long userId, @RequestParam(value="pageNum", required = false, defaultValue = "1") Long pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Long pageSize)
    {
        List<ActivityLogs> list = userCenterService.selectActivityLogsByUserID(userId, pageNum, pageSize);
        return AjaxResult.success(list);
    }

    /**
     * 获取用户低碳活动记录条数
     *  @param userId 用户ID
     *  @return 低碳活动记录条数
     */
    @GetMapping("/activityLogCount")
    public AjaxResult getActivityLogCount(@RequestParam("userId") Long userId)
    {
        Long count = userCenterService.selectActivityLogCountByUserID(userId);
        return AjaxResult.success(count);
    }

    /**
     * 获取用户低碳行为记录条数
     *  @param userId 用户ID
     *  @return 低碳行为记录条数
     */
    @GetMapping("/behaviorCount")
    public AjaxResult getBehaviorCount(@RequestParam("userId") Long userId)
    {
        Long count = userCenterService.selectBehaviorCountByUserID(userId);
        return AjaxResult.success(count);
    }

    /**
     * 获取用户地址信息
     *  @param userId 用户ID
     *  @return 低碳活动记录
     */
    @GetMapping("/address")
    public AjaxResult getAddress(@RequestParam("userId") Long userId)
    {
        startPage();
        List<Address> addressList = userCenterService.selectAddressByUserId(userId);
        return AjaxResult.success(addressList);
    }

    /**
     * 根据减碳量排名获取用户信息列表
     *  @return 用信息列表
     */
    @GetMapping("/userInfoByReduceCo2")
    public TableDataInfo getUserInfoByReduceCo2()
    {
        startPage();
        List<UserInfoVo> list = userCenterService.selectUserInfoByReduceCo2();
        return getDataTable(list);
    }

    /**
     * 根据用户减碳量进行降序排序（每日）
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 用户信息列表
     */
    @GetMapping("/userInfoByReduceCo2Day")
    public TableDataInfo getUserInfoByReduceCo2Day(@RequestParam("pageNum") Long pageNum, @RequestParam("pageSize") Long pageSize)
    {
        List<UserInfoVo> list = userCenterService.getUserInfoByReduceCo2Day(pageNum, pageSize);
        return getDataTable(list);
    }

    /**
     * 根据用户减碳量进行降序排序（每月）
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 用户信息列表
     */
    @GetMapping("/userInfoByReduceCo2Month")
    public TableDataInfo getUserInfoByReduceCo2Month(@RequestParam("pageNum") Long pageNum, @RequestParam("pageSize") Long pageSize)
    {
        List<UserInfoVo> list = userCenterService.getUserInfoByReduceCo2Month(pageNum, pageSize);
        return getDataTable(list);
    }

    /**
     * 根据组织减碳量进行降序排序
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 组织信息列表
     */
    @GetMapping("/organizationList")
    public AjaxResult getOrganizationList(@RequestParam("pageNum") Long pageNum, @RequestParam("pageSize") Long pageSize){
        List<OrganizationVo> list = userCenterService.selectOrganizationList(pageNum, pageSize);
        return AjaxResult.success(list);
    }

    /**
     * 根据组织减碳量进行降序排序（每日）
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 组织信息列表
     */
    @GetMapping("/organizationListDay")
    public AjaxResult getOrganizationListDay(@RequestParam("pageNum") Long pageNum, @RequestParam("pageSize") Long pageSize){
        List<OrganizationVo> list = userCenterService.selectOrganizationListDay(pageNum, pageSize);
        return AjaxResult.success(list);
    }

    /**
     * 根据组织减碳量进行降序排序（每月）
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 组织信息列表
     */
    @GetMapping("/organizationListMonth")
    public AjaxResult getOrganizationListMonth(@RequestParam("pageNum") Long pageNum, @RequestParam("pageSize") Long pageSize){
        List<OrganizationVo> list = userCenterService.selectOrganizationListMonth(pageNum, pageSize);
        return AjaxResult.success(list);
    }

    /**
     * 获取积分规则
     * @return 积分规则
     */
    @GetMapping("/getPointsRule")
    public AjaxResult getPointsRule(){
        return AjaxResult.success(userCenterService.getPointsRule());
    }

    /**
     * 通过地址Id获取地址信息
     * @param addressId 地址Id
     * @return 地址信息
     */
    @GetMapping("/getAddressById")
    public AjaxResult getAddressById(@RequestParam("addressId") Long addressId){
        return AjaxResult.success(addressService.selectAddressByAddressId(addressId));
    }

    /**
     * 修改地址信息
     * @param address 地址信息
     * @return 修改结果
     */
    @PutMapping("/editAddress")
    public AjaxResult editAddress(@RequestBody Address address){
        System.out.println(address.getIsDefault() == 1);
        if (address.getIsDefault() == 1){
            userCenterService.updateDefaultAddress(address.getUserId(), address.getAddressId());
        }
        return AjaxResult.success(addressService.updateAddress(address));
    }

    /**
     * 新增地址信息
     * @param address 地址信息
     * @return 新增结果
     */
    @PostMapping("/addAddress")
    public AjaxResult addAddress(@RequestBody Address address){
        if (address.getIsDefault() == 1){
            userCenterService.updateDefaultAddress(address.getUserId(), address.getAddressId());
        }
//        System.out.println(userCenterService.selectAddressByUserId(address.getUserId()).isEmpty());
        if (userCenterService.selectAddressByUserId(address.getUserId()).isEmpty()){
            address.setIsDefault(1L);
        }
        return AjaxResult.success(addressService.insertAddress(address));
    }

    /**
     * 删除地址信息
     * @param addressId 地址Id
     * @return 删除结果
     */
    @PutMapping("/deleteAddress")
    public AjaxResult deleteAddress(@RequestParam("addressId") Long addressId){
        userCenterService.deleteAddressByAddressId(addressId);
        return AjaxResult.success();
    }

    /**
     * 根据用户ID获取待付款的订单列表
     * @param userId 用户ID
     * @return 个人订单列表
     */
    @GetMapping("/selectNoPayOrder")
    public AjaxResult selectNoPayOrder(@RequestParam("userId") Long userId, @RequestParam(value="pageNum", required = false) Long pageNum, @RequestParam(value = "pageSize", required = false) Long pageSize){
        List<NoPayOrderVo> list = userCenterService.selectNoPayOrder(userId, pageNum, pageSize);
        return AjaxResult.success(list);
    }

    /**
     * 根据用户ID获取已付款的订单列表
     * @param userId 用户ID
     * @return 个人订单列表
     */
     @GetMapping("/selectPayedOrder")
    public AjaxResult selectPayedOrder(@RequestParam("userId") Long userId, @RequestParam(value="pageNum", required = false, defaultValue = "1") Long pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Long pageSize, @RequestParam(value = "goodsName", required = false, defaultValue = "") String goodsName){
        List<PayedOrderVo> list = userCenterService.selectPayedOrder(userId, pageNum, pageSize, goodsName);
        return AjaxResult.success(list);
    }

    /**
     * 根据订单中的商品名获取订单列表
     * @param goodsName 商品名
     * @return 待付款和已付款订单列表
     */
    @GetMapping("/selectOrderByGoodsName")
    public AjaxResult selectOrderByGoodsName(@RequestParam("userId") Long userId, @RequestParam("goodsName") String goodsName, @RequestParam(value="pageNum", required = false, defaultValue = "1") Long pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Long pageSize){
        Map<String ,Object> orderList = userCenterService.selectOrderByGoodsName(userId, goodsName, pageNum, pageSize);
        return AjaxResult.success(orderList);
    }

    /**
     * 获取用户积分
     * @param userId 用户ID
     * @return 用户积分
     */
    @GetMapping("/getUserPoints")
    public AjaxResult getUserPoints(@RequestParam("userId") Long userId){
        return AjaxResult.success(userCenterService.getUserPoints(userId));
    }

    /**
     * 获取减碳量、积分、人民币转换比例
     * @return 转换比例
     */
    @GetMapping("/getConversionRate")
    public AjaxResult getConversionRate(){
        return AjaxResult.success(userCenterService.getConversionRate());
    }

    /**
     * 确认收货
     * @param orderItemId 订单项ID
     * @return 确认收货结果
     */
    @PutMapping("/confirmReceipt")
    public AjaxResult confirmReceipt(@RequestParam("orderItemId") Long orderItemId){
        userCenterService.confirmReceipt(orderItemId);
        return AjaxResult.success();
    }

    /**
     * 新增商品评价
     * @param goodsEvaluate 商品评价信息
     * @return 结果
     */
    @PostMapping("/addGoodsEvaluate")
    public AjaxResult addGoodsEvaluate(@RequestBody GoodsEvaluate goodsEvaluate){
        userCenterService.addGoodsEvaluate(goodsEvaluate);
        return AjaxResult.success();
    }

    /**
     * 修改商品评价
     * @param goodsEvaluate 商品评价信息
     * @return 结果
     */
    @PutMapping("/updateGoodsEvaluate")
    public AjaxResult updateGoodsEvaluate(@RequestBody GoodsEvaluate goodsEvaluate){
        userCenterService.updateGoodsEvaluate(goodsEvaluate);
        return AjaxResult.success();
    }

    /**
     * 根据订单项获取商品评价
     * @param orderItemId 订单项ID
     * @return 商品评价
     */
    @GetMapping("/getGoodsEvaluateByOrderItemId")
    public AjaxResult getGoodsEvaluateByOrderItemId(@RequestParam("orderItemId") Long orderItemId){
        GoodsEvaluate goodsEvaluate = userCenterService.getGoodsEvaluateByOrderItemId(orderItemId);
        System.out.println(goodsEvaluate);
        return AjaxResult.success(goodsEvaluate);
    }

    /**
     * 删除订单项商品评价
     * @param orderItemId 订单项ID
     * @return 删除结果
     */
    @PutMapping("/deleteGoodsEvaluateByOrderItemId")
    public AjaxResult deleteGoodsEvaluateByOrderItemId(@RequestParam("orderItemId") Long orderItemId){
        userCenterService.deleteGoodsEvaluateByOrderItemId(orderItemId);
        return AjaxResult.success();
    }

    /**
     * 新增退款
     * @param refund 退款信息
     * @return 结果
     */
    @PostMapping("/addRefund")
    public AjaxResult addRefund(@RequestBody Refund refund){
        userCenterService.addRefund(refund);
        return AjaxResult.success();
    }

    /**
     * 重新提交退款
     * @param refund 退款信息
     * @return 结果
     */
    @PutMapping("/reSubmitRefund")
    public AjaxResult reSubmitRefund(@RequestBody Refund refund){
        System.out.println(refund);
        userCenterService.reSubmitRefund(refund);
        return AjaxResult.success();
    }

    /**
     * 根据订单项ID获取订单项信息
     * @param orderItemId 订单项ID
     * @return 订单项信息
     */
    @GetMapping("/getOrderItemById")
    public AjaxResult getOrderItemById(@RequestParam("orderItemId") Long orderItemId){
        return AjaxResult.success(orderItemService.selectOrderItemByOrderItemId(orderItemId));
    }

    /**
     * 获取订单项最大可退款数
     */
    @GetMapping("/getMaxRefundNum")
    public AjaxResult getMaxRefundNum(@RequestParam("orderItemId") Long orderItemId){
        return AjaxResult.success(userCenterService.getMaxRefundNum(orderItemId));
    }

    /**
     * 获取指定订单项ID的退款记录
     * @param orderItemId 订单项ID
     * @return 退款记录
     */
     @GetMapping("/getRefundRecordByOrderItemId")
    public AjaxResult getRefundRecordByOrderItemId(@RequestParam("orderItemId") Long orderItemId){
        return AjaxResult.success(userCenterService.getRefundRecordByOrderItemId(orderItemId));
    }

    /**
     * 获取用户的订单记录
     * @param userId 用户ID
     * @return 订单记录
     */
    @GetMapping("/getOrderInfoList")
    public AjaxResult getOrderInfoList(@RequestParam("userId") Long userId, @RequestParam(value="pageNum", required = false, defaultValue = "1") Long pageNum, @RequestParam(value = "pageSize", required = false, defaultValue = "10") Long pageSize){
        List<OrderInfo> list = userCenterService.getOrderInfoList(userId, pageNum, pageSize);
        return AjaxResult.success(list);
    }

    /**
     * 获取用户的订单记录条数
     * @param userId 用户ID
     * @return 订单记录条数
     */
    @GetMapping("/getOrderInfoCount")
    public AjaxResult getOrderInfoCount(@RequestParam("userId") Long userId){
        Long count = userCenterService.getOrderInfoCount(userId);
        return AjaxResult.success(count);
    }

    /**
     * 获取用户当天当月的减碳量,包括个人和组织
     * @param userId 用户ID
     * @return 减碳量
     */
    @GetMapping("/getUserReduceCo2")
    public AjaxResult getUserReduceCo2(@RequestParam("userId") Long userId){
        return AjaxResult.success(userCenterService.getUserReduceCo2(userId));
    }

    /**
     * 用户是否有密码
     * @param userId 用户ID
     * @return 是否有密码
     */
    @GetMapping("/hasPassword")
    public AjaxResult hasPassword(@RequestParam("userId") Long userId){
        return AjaxResult.success(userCenterService.hasPassword(userId));
    }

    /**
     * 修改密码
     * @param userId 用户ID
     * @param originalPassword 原密码
     * @param newPassword 新密码
     * @return 修改结果
     */
    @PutMapping("/changePassword")
    public AjaxResult changePassword(@RequestParam("userId") Long userId, @RequestParam("originalPassword") String originalPassword, @RequestParam("newPassword") String newPassword) {
        return AjaxResult.success(userCenterService.changePassword(userId, originalPassword, newPassword));
    }

    /**
     * 获取用户的sessionKey
     * @param userId 用户ID
     * @return sessionKey
     */
    @GetMapping("/getSessionKey")
    public AjaxResult getSessionKey(@RequestParam("userId") Long userId){
        return AjaxResult.success(userCenterService.getSessionKey(userId));
    }

}
